<template>
  <div>
    <!-- 1.用户列表第一步 添加面包屑区域 在element.js组件中导入相应的组件 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
      <el-breadcrumb-item>用户列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 2.卡片区域 -->
    <el-card>
      <!-- 3.在卡片区域添加分栏间隔 -->
      <el-row :gutter="20">
        <el-col :span="8">
          <!-- 添加搜索框 -->
          <el-input
            placeholder="请输入内容"
            v-model="userInfo.query"
            clearable
            @clear="getUserlist"
            class="input-with-select"
          >
            <el-button slot="append" icon="el-icon-search" @click="getUserlist"></el-button>
          </el-input>
        </el-col>
        <el-col :span="4">
          <el-button type="primary" @click="addDialogVisible = true">添加用户</el-button>
        </el-col>
      </el-row>
      <!-- 4.添加列表数据栏区域 在element的Table中 然后再导入组件 border 默认带边框 stripe带斑马纹 -->
      <!-- 5. 渲染后台的数据到表格中 采用axios调用后台接口完成数据的渲染 -->
      <el-table border stripe :data="userlist" style="width: 100%">
        <el-table-column align="center" type="index"></el-table-column>
        <el-table-column align="center" prop="username" label="姓名" width="180"></el-table-column>
        <el-table-column align="center" prop="email" label="邮箱" width="180"></el-table-column>
        <el-table-column align="center" prop="mobile" label="电话"></el-table-column>
        <el-table-column align="center" prop="role_name" label="角色"></el-table-column>
        <!-- 通过开关显示状态栏 -->
        <el-table-column align="center" label="状态">
          <!-- 通过作用域插槽来讲角色状态与开关绑定 并导入开关组件 row是自定义的名字 -->
          <template slot-scope="scope">
            <el-switch v-model="scope.row.mg_state" @change="userStateChage(scope.row)"></el-switch>
          </template>
        </el-table-column>
        <el-table-column align="center" label="操作">
          <template slot-scope="scope">
            <el-button plain type="primary" icon="el-icon-edit" @click="editUser(scope.row.id)"></el-button>
            <el-button plain type="warning" icon="el-icon-delete" @click="deleteUser(scope.row.id)"></el-button>
            <!-- 当鼠标移到按钮上时候回有提示 使用tooltip组件 enterable表示鼠标是否可以进入tooltip中-->
            <el-tooltip effect="dark" content="分配角色" placement="top" :enterable="true">
              <el-button plain type="danger" icon="el-icon-setting" @click="setRole(scope.row)"></el-button>
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
      <!-- 实现分页效果 -->
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="userInfo.pagenum"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="userInfo.pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
      ></el-pagination>
    </el-card>
    <!-- 添加用户 :visible.sync控制隐藏 -->
    <el-dialog title="添加用户" :visible.sync="addDialogVisible" width="50%" @close="addDialogColse">
      <!-- 内容部分 -->
      <el-form ref="addFormRef" :model="addForm" :rules="addFormRules" label-width="70px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="addForm.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="addForm.password"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="addForm.email"></el-input>
        </el-form-item>
        <el-form-item label="手机号" prop="mobile">
          <el-input v-model="addForm.mobile"></el-input>
        </el-form-item>
      </el-form>
      <!-- 底部区域 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addUser">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 编辑用户弹框 -->
    <el-dialog title="编辑用户" :visible.sync="editDialogVisible" width="50%" @close="editDialogClose">
      <el-form ref="editFormRef" :model="editForm" :rules="editFormRules" label-width="80px">
        <!-- 用户名 -->
        <el-form-item label="用户名" prop="username">
          <el-input v-model="editForm.username" disabled></el-input>
        </el-form-item>
        <!-- 邮箱 -->
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="editForm.email"></el-input>
        </el-form-item>
        <!-- 手机号码 -->
        <el-form-item label="手机" prop="mobile">
          <el-input v-model="editForm.mobile"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editUserlist">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 点击分配角色对话框 -->
    <el-dialog title="分配角色" :visible.sync="allotRoleDialog" width="50%" @close="allotClear">
      <div>
        <p>用户角色: {{queryInfo.username}}</p>
        <p>用户描述: {{queryInfo.role_name}}</p>
        <p>
          分配新角色:
          <el-select v-model="selectRolesId" placeholder="请选择">
            <el-option
              v-for="item in roleList"
              :key="item.id"
              :label="item.roleName"
              :value="item.id"
            ></el-option>
          </el-select>
        </p>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="allotRoleDialog = false">取 消</el-button>
        <el-button type="primary" @click="allotRole">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data () {
    // 定义邮箱的验证规则
    const checkEmail = (rule, value, callback) => {
      // rule表示验证的规则 value表示输入框输入的值 callback返回一个回调函数
      const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/
      // 测试输入的值是否合法
      // 验证成功
      if (regEmail.test(value)) {
        return callback()
      }
      // 验证不成功
      callback(new Error('您输入的邮箱格式不正确'))
    }
    // 定义手机号的验证规则
    const checkMobile = (rule, value, callback) => {
      const regMobile = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
      if (regMobile.test(value)) {
        return callback()
      }
      // 验证不成功
      callback(new Error('您输入的手机号不正确'))
    }

    return {
      // 获取列表的参数对象
      userInfo: {
        query: '',
        pagenum: 1, // 当前是第几页
        pagesize: 10 // 当前页的条数
      },
      // 定义一个空的数组 接收后台数据
      userlist: [],
      // 定义一个总数
      total: 0,
      // 定义修改提示框的显示与隐藏
      addDialogVisible: false,
      // 定义addForm
      addForm: {
        username: ''
      },
      // 定义验证规则
      addFormRules: {
        // 验证用户名
        username: [
          { required: true, message: '请输入登录账号', trigger: 'blur' },
          { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
        ], // 验证密码是否合法
        password: [
          { required: true, message: '请输入登录密码', trigger: 'blur' },
          { min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
        ],
        // 验证密码是否合法
        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' }
        ],
        // 验证密码是否合法
        mobile: [
          { required: true, message: '请输入手机号码', trigger: 'blur' },
          { validator: checkMobile, trigger: 'blur' }
        ]
      },
      // 定义一个编辑弹出框的显示与隐藏
      editDialogVisible: false,
      // 定义一个edit编辑数组接收后台数据
      editForm: {},

      editFormRules: {
        // 验证密码是否合法
        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' }
        ],
        // 验证密码是否合法
        mobile: [
          { required: true, message: '请输入手机号码', trigger: 'blur' },
          { validator: checkMobile, trigger: 'blur' }
        ]
      },

      // 定义编辑用户角色对话框的显示和隐藏
      allotRoleDialog: false,

      // 定义一个接收获取数据的数组
      roleList: [],

      // 定义一个接收用户信息参数的对象
      queryInfo: {},

      // 定义一个被选中角色id
      selectRolesId: ''
    }
  },
  created () {
    // 调用渲染用户列表的函数
    this.getUserlist()
  },
  methods: {
    // 定义一个获取数据的函数 这里才用的是异步获取数据 所以使用aixos
    async getUserlist () {
      const { data: res } = await this.$http.get('/users', { params: this.userInfo })
      // 判断条件 如果状态为200 表示获取成功 错误返回后台提示
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.userlist = res.data.users
      this.total = res.data.total
      // console.log(res)
    },
    // size-change pageSize 改变时会触发 显示每页的条数 handleSizeChange函数点击是更改每页的条数
    handleSizeChange (newsize) {
      // console.log(newsize)
      // 将当前更改的显示条数赋值给原来的
      this.userInfo.pagesize = newsize
      // 更改后渲染类列表
      this.getUserlist()
    },
    // current-change currentPage 改变时会触发 显示当前页是第几页 handleCurrentChange点击更改当前的页码
    handleCurrentChange (newPage) {
      // 将当前更改的显示页码赋值给原来的
      this.userInfo.pagenum = newPage
      // 更改后渲染类列表
      this.getUserlist()
    },
    // 点击开关监控状态
    async userStateChage (userState) {
      // console.log(userState)
      const { data: res } = await this.$http.put(`users/${userState.id}/state/${userState.mg_state}`)
      // 判断是否获取成功
      if (res.meta.status !== 200) {
        // 过不成功就取反
        userState.mg_state = !userState.mg_state
        return this.$message.error(res.meta.msg)
      }
      return this.$message.success(res.meta.msg)
    },
    // 在el-dialog定义一个close关闭事件事件 自定义一个函数 当表单关闭时 清空表单resetFields()
    addDialogColse () {
      this.$refs.addFormRef.resetFields()
    },
    // 给确定按钮添加一个点击事件 添加新用户 当点击开始后进行预校验 然后校验成功后发送请求
    addUser () {
      this.$refs.addFormRef.validate(async valid => {
        // 开始校验 如果
        // console.log(valid) 是一个boolean值
        if (!valid) return
        // 成功之后开始调用接口发送post请求
        const { data: res } = await this.$http.post('/users', this.addForm)
        // 调用接口失败 返回后台数据
        if (res.meta.status !== 201) return this.$message.error(res.meta.msg)
        // 返回成功提示信息
        this.$message.success(res.meta.msg)
        // 关闭弹框
        this.addDialogVisible = false
        // 成功后渲染数据
        this.getUserlist()
      })
    },
    // 编辑用户的信息 首先根据id获取到后台数据渲染到页面上
    async editUser (id) {
      // 第一步根据id获取数据渲染到页面上去
      // console.log(id)
      const { data: res } = await this.$http.get(`/users/${id}`)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.editForm = res.data
      // 打开弹框
      this.editDialogVisible = true
    },
    // 给编辑的Dialog弹出框添加一个事件 当关闭按钮时清空表单
    editDialogClose () {
      this.$refs.editFormRef.resetFields()
    },
    // 点击弹框的触发事件 先进性预校验 然后请求数据更新渲染列表
    editUserlist () {
      // 进行预校验 成功之后进行下一步操作
      this.$refs.editFormRef.validate(async valid => {
        // console.log(valid)
        if (!valid) return
        // 成功之后发送请求
        const { data: res } = await this.$http.put('/users/' + this.editForm.id, {
          email: this.editForm.email,
          mobile: this.editForm.mobile
        })
        if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
        // 更新成功之后
        // 成功信息
        this.$message.success(res.meta.msg)
        // 渲染列表
        this.getUserlist()
        // 关闭弹框
        this.editDialogVisible = false
      })
    },
    // 根据id删除 相应的用户信息
    async deleteUser (id) {
      // console.log(id) 这里的confirm是个promise对象可以使用async 和 await
      const confirmResult = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch(err => err)
      // 如果数值不等于confirm 取消删除
      if (confirmResult !== 'confirm') {
        return this.$message.info('已取消删除')
      }
      // 调用接口删除数据
      const { data: res } = await this.$http.delete('/users/' + id)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.$message.success(res.meta.msg)
      this.getUserlist()
    },

    // 获取所有角色的信息 渲染到页面上
    async setRole (queryInfo) {
      this.queryInfo = queryInfo
      const { data: res } = await this.$http.get('roles')
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.roleList = res.data
      this.allotRoleDialog = true
      // console.log(res.data)
    },
    // 点击确定 提交修改数据
    async allotRole () {
      if (!this.selectRolesId) return this.$message.error('请选择要分配的角色')
      const { data: res } = await this.$http.put(`/users/${this.queryInfo.id}/role`, {
        rid: this.selectRolesId
      })
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.$message.success(res.meta.msg)
      this.getUserlist()
      this.allotRoleDialog = false
    },

    // 设置一个关闭事件
    allotClear () {
      this.selectRolesId = ''
      this.queryInfo = {}
    }
  }
}
</script>
<style lang="less" scoped>
// 设置分配角色样式
.el-dialog p {
  margin: 0px 0px 15px 15px;
}
</style>
